Skip to content

feat(mcp): read-only MCP server (search_notes, list_notes, get_note)#23

Merged
shahid-io merged 1 commit into
mainfrom
feature/mcp-server
May 13, 2026
Merged

feat(mcp): read-only MCP server (search_notes, list_notes, get_note)#23
shahid-io merged 1 commit into
mainfrom
feature/mcp-server

Conversation

@shahid-io

Copy link
Copy Markdown
Owner

Summary

  • Adds `inode mcp` — a Model Context Protocol stdio server so MCP-aware clients (Claude Code, Cursor) can read the inode KB.
  • Three read-only tools: `search_notes`, `list_notes`, `get_note`. No write tools — writing from an agent is reserved for a future iteration.
  • Sensitive notes are excluded from `search_notes` results (the calling LLM never sees their content) and masked in `get_note`. Opt-in plaintext via `inode config set mcp.reveal_sensitive true`.

Design notes

  • Why no LLM step in search_notes: the calling host is itself an LLM (Claude, Cursor's model). Handing it raw note candidates beats handing it a pre-generated answer from a smaller local model. Refactored `SearchService.Search` to call a new `Retrieve` method (embed → vec search → threshold → decrypt) — `Search` adds the LLM-answer step on top for the CLI; MCP uses `Retrieve` directly.
  • Sensitive handling: pushed down to the DB layer via `db.Filters.IsSensitive` so sensitive notes don't reach the LLM at all (not even via decrypted-then-masked). Safer than relying on output-side scrubbing.
  • SDK choice: `github.com/mark3labs/mcp-go v0.54.0` (community-mature; bigger ecosystem of examples than the official go-sdk).

Test plan

  • 11 new unit tests covering the format functions and the sensitive-masking gates (`go test ./internal/mcp/...`)
  • Full suite green (`go test ./...`)
  • Manual: wire into Claude Code's MCP config and call each tool from an agent session
  • Manual: with `mcp.reveal_sensitive=true`, verify a credentials-category note returns plaintext

Wiring it up (Claude Code example)

```json
{
"mcpServers": {
"inode": { "command": "inode", "args": ["mcp"] }
}
}
```

🤖 Generated with Claude Code

inode mcp runs as a Model Context Protocol stdio server so MCP-aware
clients (Claude Code, Cursor) can read the knowledge base. Read-only
by design — writing is reserved for a future iteration so an agent
can't fill or wipe the KB without the user's intent showing up
anywhere reviewable.

Sensitive notes are excluded from search_notes results entirely (not
just masked in the formatted output) so the calling LLM never sees
their content. get_note returns masked content for sensitive notes
with metadata still flowing through. The new mcp.reveal_sensitive
config flag opts in to plaintext.

Adds a Retrieve method on SearchService that runs the embed → vector
search → threshold → decrypt pipeline without the LLM-answer step.
The MCP search tool uses this directly — letting the calling agent
reason over raw candidates beats handing it a pre-generated answer
from a smaller local model. The CLI's Search wraps Retrieve and adds
the LLM step on top.

SDK: github.com/mark3labs/mcp-go v0.54.0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@shahid-io
shahid-io merged commit 241623b into main May 13, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant